/* 
 * File:   ResourceLoaders.h
 * Author: RedEyedKiller
 *
 * Created on 22 Ιούνιος 2011, 3:34 πμ
 */

#ifndef RESOURCELOADERS_H
#define	RESOURCELOADERS_H

#include "../sdl/Image.h"
#include "../sdl/Font.h"
#include "../sdl/SDLException.h"
#include "../sdl/Texture.h"
#include "../audio/Sound.h"
#include <sstream>
#include <assert.h>

/**
 * In this file template loader is described which is used by ResourcePools
 * in order to load resources. All resource loading logic is encapsulated in 
 * the loader.
 * 
 * For each different resource type a specialization of Loader must exist.
 */

template <typename Type>
struct Loader
{

    bool operator()(Type** data, const std::string& defaultPath) const
    {
        //g++ is coomplaining about these, thus I disable them for the moment
        //LOGERROR << "Unspeciallized Loader was invoked!" << SOURCE;
        //assert(0 && "Unspeciallized Loader was invoked!");

        return false;
    }

    const char* GetKey() const
    {
        //g++ is complaining about these, thus I disable them for the moment
        //LOGERROR << "Unspeciallized Loader was invoked!" << SOURCE;
        //assert(0 && "Unspeciallized Loader was invoked!");

        return false;
    }
};

/**
 * Specialization of Loader for sdl::Image
 */
template <>
struct Loader<sdl::Image>
{

    bool operator()(sdl::Image** data, const std::string& defaultPath) const
    {
        try
        {
            if (this->path.empty())
            {
                *data = new sdl::Image((defaultPath + request).c_str());
            }
            else
            {
                *data = new sdl::Image((this->path + request).c_str());
            }
            return true;
        }
        catch (sdl::Exception& e)//unsuccessful load
        {
            return false;
        }
    }

    const char* GetKey() const
    {
        return request.c_str();
    }

    std::string request;
    std::string path;
};

/**
 * Specialization of Loader for sdl::Font
 */
template <>
struct Loader<sdl::Font>
{

    bool operator()(sdl::Font** data, const std::string& defaultPath) const
    {
        try
        {
            if (this->path.empty())
            {
                *data = new sdl::Font((defaultPath + request).c_str(), size);
            }
            else
            {
                *data = new sdl::Font((this->path + request).c_str(), size);
            }
            return true;
        }
        catch (sdl::Exception& e)//unsuccessful load
        {
            return false;
        }
    }

    const char* GetKey() const
    {
        std::ostringstream oss;
        oss << request << size;
        return oss.str().c_str();
    }

    std::string request;
    std::string path;
    int size;
};

/**
 *  Specialization of loader class for Texture
 */
template <>
struct Loader<gl::Texture>
{

    bool operator()(gl::Texture** data, const std::string& defaultPath) const
    {
        try
        {
            if (this->path.empty())
            {
                *data = new gl::Texture;
                (*data)->Load((defaultPath + request).c_str());
            }
            else
            {
                *data = new gl::Texture;
                (*data)->Load((this->path + request).c_str());
            }
            return true;
        }
        catch (sdl::Exception& e)//unsuccessful load
        {
            return false;
        }
    }

    const char* GetKey() const
    {
        return request.c_str();
    }

    std::string request;
    std::string path;
};

/**
 *  Specialization of loader class for Sound
 */
template <>
struct Loader<al::Sound>
{
    bool operator()(al::Sound** data, const std::string& defaultPath) const
    {
        *data = new al::Sound;
        if(request.find(".wav",0,4) != request.npos)
        {
            return (*data)->LoadWAV((defaultPath + request).c_str());
        }
        else if (request.find(".ogg",0,4) != request.npos)
        {
            return (*data)->LoadOGG((defaultPath + request).c_str());
        }
        else
        {
            return false;
        }
    }

    const char* GetKey() const
    {
        return request.c_str();
    }

    std::string request;
    std::string path;
};

#endif	/* RESOURCELOADERS_H */
